package or.exa.cangguan.service.impl;

import cn.hutool.core.bean.BeanUtil;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import or.exa.cangguan.common.Page;
import or.exa.cangguan.entity.dto.GoodsDto;
import or.exa.cangguan.entity.dto.OutOperationDto;
import or.exa.cangguan.entity.po.Goods;
import or.exa.cangguan.entity.po.GoodsPlace;
import or.exa.cangguan.entity.po.OutOperation;
import or.exa.cangguan.entity.po.OutOperationDetail;
import or.exa.cangguan.entity.vo.GoodsVo;
import or.exa.cangguan.entity.vo.OutOperationVo;
import or.exa.cangguan.mapper.*;
import or.exa.cangguan.service.OutOperationService;
import or.exa.cangguan.service.OutStoreService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class OutOperationServiceImpl implements OutOperationService {
    @Autowired
    private OutOperationMapper outOperationMapper;
    @Autowired
    private OutOperationDetailMapper outOperationDetailMapper;
    @Autowired
    private LoadingPositionMapper loadingPositionMapper;
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private ShelfMapper shelfMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private OutStoreService outStoreService;
    @Autowired
    private OutStoreMapper outStoreMapper;
    @Autowired
    private GoodsPlaceMapper goodsPlaceMapper;


    @Override
    public Page searchOutOperation(OutOperationVo outOperationVo) {
        Page page = new Page();
        BeanUtil.copyProperties(outOperationVo, page);
        List<OutOperationDto> outOperationDtos = outOperationMapper.selectByPrimaryKey(outOperationVo,page);
        page.setResultList(outOperationDtos);

        Integer totalNum = outOperationMapper.selectCount(outOperationVo);
        page.setTotalNum(totalNum);

        log.info("outOperationDtos: {}", outOperationDtos);

        return page;
    }

    @Override
    public Integer addOutOperation(OutOperationVo outOperationVo) {
        Date date = new Date(System.currentTimeMillis());
        log.info("outOperationVo: {}", outOperationVo);

        OutOperation outOperation = new OutOperation();
        BeanUtil.copyProperties(outOperationVo, outOperation);
        outOperation.setCreateTime(date);
        outOperation.setCreateBy(0);
        outOperation.setUpdateBy(0);
        outOperation.setUpdateTime(date);
        String code = loadingPositionMapper.selectByPrimaryKey(outOperationVo.getLoadName());
        outOperation.setLoadCode(code);
        log.info("outOperation before exeWorker: {}", outOperation);

        Integer exeWorker = employeeMapper.selectByName(outOperationVo.getExeWorkerName());
        outOperation.setExeWorker(exeWorker);
        log.info("outOperation after exeWorker: {}", outOperation);

        int i = outOperationMapper.insertSelective(outOperation);

        List<Goods> goods = goodsMapper.selectByName(outOperationVo.getGoodsList());
        int detailCount = 0;
        for (GoodsVo goodsVo : outOperationVo.getGoodsList()) {
            OutOperationDetail outOperationDetail = new OutOperationDetail();
            outOperationDetail.setCreateTime(date);
            outOperationDetail.setCreateBy(0);
            outOperationDetail.setUpdateBy(0);
            outOperationDetail.setUpdateTime(date);
            outOperationDetail.setShelfId(shelfMapper.selectIdByName(goodsVo.getShelfName()));
            outOperationDetail.setGoodsCount(goodsVo.getGoodsCount());
            outOperationDetail.setOutOperationId(outOperation.getId());

            for (Goods good : goods) {
                if (good.getGoodsName().equals(goodsVo.getGoodsName())) {
                    outOperationDetail.setGoodsId(good.getGoodsId());
                    break;
                }
            }
            detailCount += outOperationDetailMapper.insert(outOperationDetail);
        }

        return i > 0 && detailCount == outOperationVo.getGoodsList().size() ? 1 : 0;
    }


    //更新出库作业单
    @Override
    public Integer updateOutOperation(OutOperationVo outOperationVo) {
        Date date = new Date(System.currentTimeMillis());
        OutOperation outOperation = new OutOperation();
        BeanUtil.copyProperties(outOperationVo, outOperation);
        outOperation.setUpdateBy(0);
        outOperation.setUpdateTime(date);

        String code = null;
        if (outOperationVo.getLoadName() != null && !outOperationVo.getLoadName().isEmpty()) {
            code = loadingPositionMapper.selectByPrimaryKey(outOperationVo.getLoadName());
            outOperation.setLoadCode(code);
        }

        Integer exeWorker = null;
        if (outOperationVo.getExeWorkerName() != null && !outOperationVo.getExeWorkerName().isEmpty()) {
            exeWorker = employeeMapper.selectByName(outOperationVo.getExeWorkerName());
            outOperation.setExeWorker(exeWorker);
        }

        int i = outOperationMapper.updateByPrimaryKeySelective(outOperation);
        outOperationDetailMapper.deleteByPrimaryKey(outOperation.getId());
        log.info("outOperation after exeWorker: {}", outOperation);

        List<Goods> goods = goodsMapper.selectByName(outOperationVo.getGoodsList());
        log.info("goods: {}", goods);
        int detailCount = 0;
        for (GoodsVo goodsVo : outOperationVo.getGoodsList()) {
            OutOperationDetail outOperationDetail = new OutOperationDetail();
            outOperationDetail.setCreateTime(date);
            outOperationDetail.setCreateBy(0);
            outOperationDetail.setUpdateBy(0);
            outOperationDetail.setUpdateTime(date);
            outOperationDetail.setShelfId(shelfMapper.selectIdByName(goodsVo.getShelfName()));
            outOperationDetail.setGoodsCount(goodsVo.getGoodsCount());
            outOperationDetail.setOutOperationId(outOperation.getId());

            for (Goods good : goods) {
                if (good.getGoodsName().equals(goodsVo.getGoodsName())) {
                    outOperationDetail.setGoodsId(good.getGoodsId());
                    break;
                }
            }
            detailCount += outOperationDetailMapper.insert(outOperationDetail);
        }

        return i > 0 && detailCount == outOperationVo.getGoodsList().size() ? 1 : 0;
    }

    @Override
    public List<GoodsDto> searchGoods(Integer outOperationId) {
        List<GoodsDto> goodsDtos = outOperationDetailMapper.selectByPrimaryKey(outOperationId);
        log.info("goodsDtos: {}", goodsDtos);
        return goodsDtos;
    }


    //更新状态
    @Override
    public Integer updateStatus(Integer outId, String status) {
        if (Objects.equals(status, "2"))
        {
            log.info("outId: {}", outId);
            String status1 = outOperationMapper.selectStatus(outId);
            String status2 = outStoreMapper.selectStatus(outId);
            log.info("status1-----------"+status1);
            log.info("status2-----------"+status2);
            if (status1.equals("0")){
                return -1;
            }
            outStoreService.updateStatus(outId, "1", null);
            log.info("状态已更改");
            Integer i = reduceGoods(outId, status);
            log.info("返回状态"+i);


            log.info("货物已减少");
            if (i == -1)
            {
                outStoreService.updateStatus(outId, status2, null);

                return -1;
            }


        }
        if (Objects.equals(status, "1"))
        {

            Integer name = outOperationMapper.selectExeName(outId);
            if (name==null)
                return 0;
        }

        if (Objects.equals(status, "3"))
        {
            Integer id = outOperationMapper.selectIdByOutId(outId);
            List<OutOperationDetail> outOperationDetails = outOperationDetailMapper.selectByIOId(id);
            Integer storeId = outStoreMapper.selectStoreById(outId);
            List<GoodsPlace> goodsPlaceList = goodsPlaceMapper.selectByConditionList(storeId, null, null);


            for (OutOperationDetail outOperationDetail : outOperationDetails) {
                GoodsPlace goodsPlace = new GoodsPlace();

                for (GoodsPlace goodsPlace1 : goodsPlaceList) {
                    if (goodsPlace1.getGoodsId().equals(outOperationDetail.getGoodsId())) {
                        Integer count = goodsPlaceMapper.selectFreezeCount(storeId, goodsPlace1.getShelfId(), goodsPlace1.getGoodsId());
                        if(goodsPlace1.getFreezeCount()!= null) {


                            if (outOperationDetail.getGoodsCount() > count) {
                                outOperationDetail.setGoodsCount(outOperationDetail.getGoodsCount() - count);
                                goodsPlace.setFreezeCount(0);
                                goodsPlace.setId(goodsPlace1.getId());
//                                log.info("goodsPlace: {}", goodsPlace);
                                goodsPlaceMapper.updateByPrimaryKeySelective(goodsPlace);
                            }
                            if (outOperationDetail.getGoodsCount() < count) {
                                goodsPlace.setFreezeCount(goodsPlace1.getFreezeCount()- outOperationDetail.getGoodsCount()  );
                                goodsPlace.setId(goodsPlace1.getId());
                                goodsPlaceMapper.updateByPrimaryKeySelective(goodsPlace);
                                break;
                            }
                        }
                    }
                }

            }



        }

        return outOperationMapper.updateStatus(outId, status);
    }




    //减少货物
    @Override
    public Integer reduceGoods(Integer outId, String status) {
        if (Objects.equals(status, "2")){
            Integer storeId = outStoreMapper.selectStoreById(outId);
            Integer id = outOperationMapper.selectIdByOutId(outId);
            List<OutOperationDetail> outOperationDetails = outOperationDetailMapper.selectByIOId(id);
            List<GoodsPlace> goodsPlaceList = goodsPlaceMapper.selectByConditionList(storeId, null, null);
            Integer flag = 0;
            Integer flag1 = 0;
            log.info("outOperationDetails: {}", outOperationDetails);
            log.info("goodsPlaceList: {}", goodsPlaceList);
            //判断货物是否足够
            for (OutOperationDetail outOperationDetail : outOperationDetails) {
                GoodsPlace goodsPlace = new GoodsPlace();
                Integer count = goodsPlaceMapper.selectCountByCondition(storeId, outOperationDetail.getGoodsId());
                log.info("count: {}", count);
                if (count == null) {
                    count = 0;
                }
                if(count<outOperationDetail.getGoodsCount()){
                    return -1;
                }else {
                    flag1++;
                }
                flag++;

            }

            if(flag1<flag){
                return -1;
            }

            if (flag1.equals(flag)) {
                for (OutOperationDetail outOperationDetail : outOperationDetails) {
                    GoodsPlace goodsPlace = new GoodsPlace();
//                    goodsPlace.setStoreId(storeId);
//                    goodsPlace.setGoodsId(outOperationDetail.getGoodsId());
//                    goodsPlace.setShelfId(outOperationDetail.getShelfId());
                    for (GoodsPlace goodsPlace1 : goodsPlaceList) {
//                        if (goodsPlace1.getGoodsId().equals(outOperationDetail.getGoodsId()) && goodsPlace1.getShelfId().equals(outOperationDetail.getShelfId())) {
                        if (goodsPlace1.getGoodsId().equals(outOperationDetail.getGoodsId())) {
                            Integer count = goodsPlaceMapper.selectCount(storeId, goodsPlace1.getShelfId(), goodsPlace1.getGoodsId());
                                if(goodsPlace1.getFreezeCount()== null) {
                                    goodsPlace.setFreezeCount(0);
                                }

                            if (outOperationDetail.getGoodsCount() > count) {
                                outOperationDetail.setGoodsCount(outOperationDetail.getGoodsCount() - count);
                                goodsPlace.setCount(0);
                                goodsPlace.setFreezeCount(outOperationDetail.getGoodsCount()+goodsPlace1.getFreezeCount());
                                goodsPlace.setId(goodsPlace1.getId());
//                                log.info("goodsPlace: {}", goodsPlace);
                                goodsPlaceMapper.updateByPrimaryKeySelective(goodsPlace);
                            }
                            if (outOperationDetail.getGoodsCount()<count) {
                                goodsPlace.setCount(count - outOperationDetail.getGoodsCount());
                                goodsPlace.setFreezeCount(outOperationDetail.getGoodsCount()+goodsPlace1.getFreezeCount());
                                goodsPlace.setId(goodsPlace1.getId());
                                goodsPlaceMapper.updateByPrimaryKeySelective(goodsPlace);
                                break;
                            }
                        }
                    }

                }
            }


        }


        return 1;
    }


}
